package com.example.mybatis_plus_use.Interceptor;

import com.example.mybatis_plus_use.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
@Slf4j
public class BusinessInterceptor implements HandlerInterceptor {

    @Override
    // 1. 最先执行，在Controller方法之前
    // 每个请求都会执行这里，可以对请求进行一些处理，如记录日志、性能监控、用户行为跟踪。
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) {
        // 1. 记录请求开始信息
        log.info("请求路径: {}", request.getRequestURI());
        log.info("请求方法: {}", request.getMethod());
        log.info("请求IP: {}", request.getRemoteAddr());

        // 2. 保存开始时间
        request.setAttribute("startTime", System.currentTimeMillis());
        return true;
    }
    @Override
    //postHandle (正常时执行异常不执行) 和afterCompletion（总是执行）但是一般情况下，异常在afterCompletion中处理
    // 2. Controller方法执行后、视图渲染前调用
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) {
        // 2. Controller方法执行后、视图渲染前调用
        // 注意：如果Controller抛出异常，这个方法不会被调用
        log.info("Controller执行完成");
    }
    @Override
    // 3. 视图渲染后调用
    // 无论是否有异常，这个方法都会被调用
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) {
        // 3. 计算处理时间
        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();

        // 4. 无论成功失败都记录完整日志
        log.info("请求路径: {}", request.getRequestURI());
        log.info("请求方法: {}", request.getMethod());
        log.info("请求IP: {}", request.getRemoteAddr());
        log.info("处理时间: {}ms", endTime - startTime);
        log.info("响应状态: {}", response.getStatus());

        // 5. 如果有异常也记录
        if (ex != null) {
            log.error("请求异常", ex);
        }
    }
}
/**
 * Spring Security的过滤器链在Spring MVC拦截器之前执行，
 * 所以请求可能在到达BusinessInterceptor之前就被Spring Security拦截了。
 */

//prehandle方法记录了请求日志、性能监控、用户行为跟踪。
//posthandle方法记录了处理时间。
//aftercompletion方法记录了异常。
//三者执行的quence是：preHandle -> postHandle -> afterCompletion。
//在preHandle方法中，我们可以对请求进行一些处理，如记录日志、性能监控、用户行为跟踪。
//在postHandle方法中，我们可以对响应进行一些处理，如记录处理时间。
//在afterCompletion方法中，我们可以对异常进行一些处理，如记录异常。
//prehandle是在请求dispatch到controller之前执行的，
// posthandle是在controller处理完请求之后，view渲染之前执行的，
// aftercompletion是在请求处理完成之后且视图渲染完成之后执行的。